package com.xvyy.tingshu.search.cron;

import com.xvyy.tingshu.search.service.impl.ItemServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * ClassName: RebuildDistributedBloomFilterTask
 * Package: com.xvyy.tingshu.search.cron
 *
 * @Description: 本地定时任务业务类
 * @Author: xvyy
 * @Create: 2025/2/7 - 20:17
 * @Version: v1.0
 */
@Component
@Slf4j
public class RebuildDistributedBloomFilterTask {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ItemServiceImpl itemService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

//    @Scheduled(cron = "0 0/1 * * * ?")// 每1分钟执行一次 测试环境
//    @Scheduled(cron = "0 0 2 0/7 * ?")// 每7天的凌晨2点执行 生产环境
    public void RebuildDistributedBloomFilter() {
        log.info("开始重建分布式布隆过滤器");
        // 1. 创建一个新的布隆过滤器
        RBloomFilter<Object> newBloomFilter = redissonClient.getBloomFilter("albumIdBloomFilter:new");
        newBloomFilter.tryInit(1000000L, 0.03);
        // 2. 获取最新的专辑id列表
        List<Long> albumInfoIdList = itemService.getAlbumInfoIdList();
        if (!CollectionUtils.isEmpty(albumInfoIdList)) {
            // 3. 将albumIdList添加到新的布隆过滤器中
            for (Long albumInfoId : albumInfoIdList) {
                newBloomFilter.add(albumInfoId);
            }
            newBloomFilter.add(1000000L);
            log.info("新布隆过滤器初始化完成，数据量：{}", newBloomFilter.count());
        }
        // 4. 引入Lua脚本，保证操作的原子性
        String script = " redis.call(\"del\",KEYS[1])" +
                "  redis.call(\"del\",KEYS[2])" +
                "  redis.call(\"rename\",KEYS[3],KEYS[1])" +
                "  redis.call(\"rename\",KEYS[4],KEYS[2]) return 1";
        List<String> asList = Arrays.asList("albumIdBloomFilter", "{albumIdBloomFilter}:config", "albumIdBloomFilter:new", "{albumIdBloomFilter:new}:config");
        Long execute = stringRedisTemplate.execute(new DefaultRedisScript<>(script, Long.class), asList);
        if (execute == 1) {
            log.info("新布隆过滤器重载完成");
        } else {
            log.info("新布隆过滤器重载失败，继续使用旧布隆过滤器");
            stringRedisTemplate.delete("albumIdBloomFilter:new");
            stringRedisTemplate.delete("{albumIdBloomFilter}:config");
        }
    }

    //    @Scheduled(fixedDelay = 2000)// 每2秒执行一次
//    @Scheduled(cron = "0/5 * * * * ?")// 每5秒执行一次
    public void taskTest() {
//        log.info("定时任务执行了{}", new Date());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("定时任务执行了{}", simpleDateFormat.format(new Date()));

    }
}
